﻿using QModels;
using QServices;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace QControlCenter;

public class PipelinedTcpClient : IDisposable
{
    private readonly TcpClient tcpClient;
    private readonly int Port;
    private readonly string IP;

    private ConcurrentList<string> ResultDatas { get; set; }

    public PipelinedTcpClient(string ip, int port)
    {
        IP = ip;
        Port = port;
        tcpClient = new TcpClient();
        tcpClient.Setup(new TouchSocketConfig().SetRemoteIPHost($"{IP}:{Port}"));
        tcpClient.Received += OnReceived;
        tcpClient.Connect();
        ResultDatas = new ConcurrentList<string>();
    }

    private Task OnReceived(ITcpClient client, ReceivedDataEventArgs e)
    {
        //从服务器收到信息
        string hexString = Convert.ToHexString(e.ByteBlock.Span);
        ResultDatas.Add(hexString);
        return Task.CompletedTask;

    }

    public List<string> SendDataWithReturn(params byte[][] datas)
    {
        var dts = datas.ToList();
        return SendDataWithReturn(dts);
    }
    public List<string> SendDataWithReturn(List<byte[]> datas)
    {

        var res = new List<string>();
        if (datas.Count == 0) return res;
        ResultDatas.Clear();
        foreach (byte[] data in datas)
        {
            tcpClient.Send(data);
            Thread.Sleep(150);
        }
        while (ResultDatas.Count != datas.Count)
        {
            Thread.Sleep(500);
        }
        res.AddRange(ResultDatas);
        ResultDatas.Clear();
        return res;
    }
    public void SendData(byte[] datas)
    {
        tcpClient.Send(datas);

    }


    public bool Connect()
    {
        
        tcpClient.Connect();
        return true;
    }

    public void Dispose()
    {
        tcpClient.Dispose();

    }





    public int ReadInt32(string address, string plc = "01", string readOrWrite = "03", string readLen = "0001")
    {
        var  address_bytes=CRC16Modbus.GetPlcBytesFromAddress(address,plc,readOrWrite,readLen);
        var res=SendDataWithReturn(address_bytes);
        if(res.Count<=0) return 0;
        var res_val = CRC16Modbus.GetValueFromModulBus_Int(res.First());
        return res_val;
    }

    public int ReadInt32(string name)
    {
        if(!AppRuntime.ModBusAddresses_Reader.Value.ContainsKey(name)) return 0;
        var tcpAddress = AppRuntime.ModBusAddresses_Reader.Value[name];
        var address_bytes = CRC16Modbus.GetPlcBytesFromAddress(tcpAddress);
        var res = SendDataWithReturn(address_bytes);
        if (res.Count <= 0) return 0;
        var res_val = CRC16Modbus.GetValueFromModulBus_Int(res.First());
        return res_val;

    }


    public bool Write(string name,int value)
    {
        if (!AppRuntime.ModBusAddresses_Writer.Value.ContainsKey(name)) return false;

        var tcpAddress = AppRuntime.ModBusAddresses_Writer.Value[name];
        var address_bytes = CRC16Modbus.GetPlcBytesFromAddressWriter(tcpAddress,value);
        SendData(address_bytes);
        return true;
    }










}

